﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using XchangeStreamer.Publisher.SDK;
using System.Threading.Tasks;
using System.Threading;
using XchangeStreamer.Types;
using VFNStockTrader.DAL.Oracle.MarketDataFeed.EGX;

namespace EgxPublisher
{
    class Program
    {
        private static Connector connector;

        private const string FEED_DATABASE_CONNECTION_STRING = @"USER ID=feednew;PASSWORD=WenDeef;Statement Cache Size=1;Statement Cache Purge=false;
                                                                    Connection Timeout=600;Pooling=false;
                                                                    DATA SOURCE=(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp) 
                                                                    (HOST=217.52.114.5)(PORT = 1521))(CONNECT_DATA=(SERVICE_NAME=FeedDB)))";
        private static string lastTicketNumber = "0";
        private static int lastOrderNumber = 0;
        private static long totalTradesNumber = 0;

        private static RawData ordersConnector;
        private static RawData tradesConnector;
        private static RawData symbolSummaryConnector;

        static void Main(string[] args)
        {
            Console.Write("Please enter streamer info (IP/Port):");
            string[] streamerInfo = Console.ReadLine().Split('/');

            Console.Write("Please enter cache server info (IP/Port):");
            string[] cacheServerInfo = Console.ReadLine().Split('/');

            string streamerIP = streamerInfo.Length < 2 ? "localhost" : streamerInfo[0];
            string streamerPort = streamerInfo.Length < 2 ? null : streamerInfo[1];
            string cacheServerIP = cacheServerInfo.Length < 2 ? "localhost" : cacheServerInfo[0];
            string cacheServerPort = cacheServerInfo.Length < 2 ? null : cacheServerInfo[1];

            connector = Connector.Connection;
            connector.Connect(streamerIP, streamerPort, cacheServerIP, cacheServerPort);

            connector.CreateTopic("Orders");
            connector.CreateTopic("Trades");
            connector.CreateTopic("SymbolSummary");

            var start = DateTime.UtcNow.TimeOfDay;
            Console.WriteLine("Start Time: {0}", start);

            Task.Factory.StartNew(PublishOrders);
            Task.Factory.StartNew(PublishTrades);
            Task.Factory.StartNew(PublishSymbolSummary);

            Console.ReadKey();
            connector.Disconnect();

            var end = DateTime.UtcNow.TimeOfDay;
            Console.WriteLine("End Time: {0}", end);

            Console.WriteLine("Test Time: {0}", end.Subtract(start));
            Console.ReadKey();

            ordersConnector.Close();
            ordersConnector.Dispose();

            tradesConnector.Close();
            tradesConnector.Dispose();

            symbolSummaryConnector.Close();
            symbolSummaryConnector.Dispose();
        }

        private static void PublishOrders()
        {
            ordersConnector = new RawData();
            ordersConnector.Open(FEED_DATABASE_CONNECTION_STRING);
            while (true)
            {
                var orders = ordersConnector.GetOrders(lastOrderNumber);

                if (orders.Count > 0)
                {
                    lastOrderNumber = orders[orders.Count - 1].RecSerial;
                    connector.Publish<Order, List<Order>>(1, orders);
                }
            }
        }

        private static void PublishTrades()
        {
            tradesConnector = new RawData();
            tradesConnector.Open(FEED_DATABASE_CONNECTION_STRING);
            while (true)
            {
                var trades = tradesConnector.GetTrades(lastTicketNumber);

                if (trades.Count > 0)
                {
                    lastTicketNumber = trades[trades.Count - 1].TicketNumber;
                    connector.Publish<Trade, List<Trade>>(2, trades);
                }
            }
        }

        private static void PublishSymbolSummary()
        {
            symbolSummaryConnector = new RawData();
            symbolSummaryConnector.Open(FEED_DATABASE_CONNECTION_STRING);
            while (true)
            {
                var symbolSummary = symbolSummaryConnector.GetSymbolSummary(totalTradesNumber);

                if (symbolSummary.Count > 0)
                {
                    totalTradesNumber = symbolSummary.Sum(temp => temp.CumNumTransact);
                    connector.Publish<SymbolSummary, List<SymbolSummary>>(3, symbolSummary);
                }
            }
        }
    }
}
